<template>
  <el-form ref="formRef" label-width="100px">
    <el-form-item label="SPU名称">
      <el-input placeholder="请输入SPU名称" v-model="spuParam.spuName" />
    </el-form-item>
    <el-form-item label="SPU品牌">
      <!-- 把 el-option 标签下 value属性的值收集到 el-select 标签的 v-model属性中 -->
      <el-select placeholder="请选择品牌" v-model="spuParam.tmId">
        <!-- value的作用是收集被选中的品牌的ID -->
        <el-option :label="item.tmName" v-for="item in tradeMarkList" :key="item.id" :value="item.id"></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述" prop="time">
      <!-- v-model:既展示又收集 -->
      <el-input type="textarea" placeholder="请输入描述" v-model="spuParam.description" />
    </el-form-item>
    <el-form-item label="SPU照片">
      <!-- 
      v-model:file-list->展示默认图片
      action：上传图片的接口地址
      list-type-> 文件列表类型 ： text | picture | picture-card

      -->
      <el-upload v-model:file-list="spuImageList" action="/api/dog/random" list-type="picture-card"
        :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="handlerBeforeUpload">
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 100%; height: 100%;" />
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性" prop="name">
      <!-- 展示销售属性的下拉菜单 -->
      <el-select :placeholder="unSelectSaleAttr.length ? `还未选择${unSelectSaleAttr.length}个` : `请选择`"
        v-model="saleAttrIdAndValueName">
        <el-option v-for="(item) in unSelectSaleAttr" :key="item.id" :label="item.name"
          :value="`${item.id}:${item.name}`" />
      </el-select>
      <!-- button按钮 -->
      <el-button :disabled="saleAttrIdAndValueName ? false : true" style="margin-left: 10px ;" type="primary"
        size="default" icon="Plus">添加属性</el-button>
    </el-form-item>
    <!-- table展示销售属性与属性值的地方 -->
    <el-table border style="margin:10px 0px" :data="supSaleAttrList">
      <el-table-column type="index" label="序号" width="80" align="center" />
      <el-table-column label="销售属性名字" prop="saleAttrName" width="120">
      </el-table-column>
      <el-table-column label="销售属性值" prop="address">
        <!-- row：即为当前spu已有的销售属性对象 -->
        <template #="{ row, $index }">
          <el-tag @close="row.spuSaleAttrValueList.splice(index, 1)" v-for="(item, index) in row.spuSaleAttrValueList"
            :key="item.id" class="mx-1" :closable="true">
            {{ item.saleAttrValueName }}
          </el-tag>
          <el-input v-model="row.saleAttrValue" @blur="toLook(row)" v-if="row.flag == true" placeholder="请你输入属性值"
            size="small" style="width: 100px;" />

          <el-button @click="toEdit(row)" type="primary" size="small" icon="Plus">

          </el-button>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="120">
        <template #="{ row, $index }">
          <el-button size="small" type="Danger" icon="Delete" @click="supSaleAttrList.splice($index, 1)"></el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-form-item>
      <el-button :disabled="!spuParam.spuSaleAttrList" @click="save" size="default" type="primary">保存</el-button>
      <el-button size="default" type="primary" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { SaleAttrList, SpuImageList, SpuSaleAttrList, SpuSaleAttrValueVO, SpuSaleAttrVO, SpuVO } from '@/api/product/spu/type';
import { reqAllTrademarkList, reqSpuSaleAttrList, reqAllSaleAttrList, reqSpuImageList } from '@/api/product/spu/index';
import type { TrademarkList } from '@/api/product/trademark/type';
import type { Response } from '@/api/type';
import { ElMessage } from 'element-plus';
import { reqSaveOrUpdateSpu } from '@/api/product/spu'
// 控制对话框的显示与隐藏 默认是false：（隐藏）
let dialogVisible = ref<boolean>(false);

// 存储预览图片的地址 
let dialogImageUrl = ref<string>('');

// 存储已有的spu这些数据
let tradeMarkList = ref<TrademarkList>([]);
let spuImageList = ref<SpuImageList>([]);
// spu已有的销售属性
let supSaleAttrList = ref<SpuSaleAttrList>([]);
// 所有的销售属性
let allSaleAttrList = ref<SaleAttrList>([]);

//  定义一个spuParams字段用来接收父组件传递过来的
let spuParam = ref<SpuVO>({
  spuName: '', // spu的名字
  category3Id: 0, // 将来搜集三级分类的ID
  description: '', // 描述信息
  tmId: 0, // 品牌的ID
  spuSaleAttrList: [
  ],
  spuImageList: [
  ]
});
let pageIndex = ref(1);
// 添加一个新的spu初始化请求方法
const initAddSpu = async (spu: SpuVO, pageNo: number) => {
  //清空之前的数据
  Object.assign(spuParam.value, {
    spuName: '', // spu的名字
    category3Id: 0, // 将来搜集三级分类的ID
    description: '', // 描述信息
    tmId: 0, // 品牌的ID
    spuSaleAttrList: [
    ],
    spuImageList: [
    ]
  });
  // 清空照片
  spuImageList.value = [];
  // 清空销售属性
  supSaleAttrList.value = [];
  // 清空属性信息
  saleAttrIdAndValueName.value = '';
  //获取全部品牌的spu数据
  let trademarkResult: Response<TrademarkList> = await reqAllTrademarkList();
  if (trademarkResult.code != 200) {
    ElMessage.error(trademarkResult.message);
    return
  }
  tradeMarkList.value = trademarkResult.data || [];
  // 获取所有的销售属性的数据
  let allSaleAttrResult: Response<SaleAttrList> = await reqAllSaleAttrList();
  if (allSaleAttrResult.code != 200) {
    ElMessage.error(allSaleAttrResult.message);
    return
  }
  allSaleAttrList.value = allSaleAttrResult.data || [];

  // spu:即为父组件传递过来的已有的spu对象[不完整]
  pageIndex.value = pageNo
  spuParam.value.category3Id = spu.category3Id;

}
// 初始化子组件的数据，该动作有父组件完成 此处没有被调用是一种误导
const initHashSpuData = async (spu: SpuVO, pageNo: number) => {
  // spu:即为父组件传递过来的已有的spu对象[不完整]
  pageIndex.value = pageNo
  spuParam.value = spu;
  //  获取全部品牌的数据
  let trademarkResult: Response<TrademarkList> = await reqAllTrademarkList();
  if (trademarkResult.code != 200) {
    ElMessage.error(trademarkResult.message);
    return
  }
  tradeMarkList.value = trademarkResult.data || [];
  // 获取某一个品牌旗下的全部售卖商品图片
  let imgResult: Response<SpuImageList> = await reqSpuImageList(spu.id as number); // 断言为number类型
  if (imgResult.code != 200) {
    ElMessage.error(imgResult.message);
    return
  }
  spuImageList.value = (imgResult.data || []).map((item) => {
    item.url = item.imgUrl;
    item.name = item.imgName;
    return item
  })

  // 获取已有的spu销售属性的数据
  let saleAttrResult: Response<SpuSaleAttrList> = await reqSpuSaleAttrList(spu.id as number);
  if (saleAttrResult.code != 200) {
    ElMessage.error(saleAttrResult.message);
    return
  }
  supSaleAttrList.value = saleAttrResult.data || [];
  // 获取整个项目全部spu的销售属性
  let allSaleAttrResult: Response<SaleAttrList> = await reqAllSaleAttrList();
  if (allSaleAttrResult.code != 200) {
    ElMessage.error(allSaleAttrResult.message);
    return;
  }
  allSaleAttrList.value = allSaleAttrResult.data || [];
}

const toLook = (row: SpuSaleAttrVO) => {
  // 整理收集的属性的ID与属性值的名称
  let { baseSaleAttrId, saleAttrValue } = row;
  if (saleAttrValue == null || saleAttrValue.trim() == '') {
    ElMessage.error('请输入属性值名称');
    return;
  }
  // 整理成服务器需要的属性形式
  let newSaleAttrValue: SpuSaleAttrValueVO = {
    baseSaleAttrId,
    saleAttrValueName: saleAttrValue
  }
  // 如果不存在给一个空数组
  if (!row.spuSaleAttrValueList) {
    // 创建一个空的属性值数组
    row.spuSaleAttrValueList = [];
  }
  // 判断属性值的数组是否在列表中已经存在
  if (row.spuSaleAttrValueList.find(item => item.saleAttrValueName == saleAttrValue)) {
    ElMessage.error('属性值名称不能重复');
    return;
  }
  // 追加新的属性值对象
  row.spuSaleAttrValueList.push(newSaleAttrValue);
  // 切换为查看模式
  row.flag = true;


}

// 属性值按钮的点击事件
const toEdit = (row: SpuSaleAttrVO) => {
  // 点击按钮的时候 input组件就出来了
  row.flag = true;

}
//  根据ID删除销售属性信息
const handlerDelAttr = (row: SpuSaleAttrVO) => {
  // todo something


}

//  照片墙上传前的勾子程序
const handlerBeforeUpload = (file: any) => {
  // 约束文件的类型和大小
  if (!(
    file.type == 'image/jpg' ||
    file.type == 'image/jpeg' ||
    file.type == 'image/png' ||
    file.type == 'image/gif'
  )) {
    ElMessage.error('文件格式不支持');
    return false;
  }
  // 约束文件的大小
  return true;


}
// 照片墙删除图片的勾子
const handleRemove = () => {
  // todo something
}
// 照片墙点击预览按钮的时候触发的勾子
const handlePictureCardPreview = (file: any) => {


  // 对话框内图片的地址
  dialogImageUrl = file.url;

  // 对话框弹窗 弹出来
  dialogVisible.value = true;

  // todo something
}

const $emit = defineEmits(['changeScene'])

const cancel = () => {
  $emit('changeScene', { flag: 0, params: 'update' })
}

// 将来收集还未选择的销售属性的id和属性值的名字
let saleAttrIdAndValueName = ref<string>('');

// 计算出当前spu还未拥有的销售属性
let unSelectSaleAttr = computed(() => {
  // 获取已有的销售属性
  let saleAttrList = allSaleAttrList.value.filter((item) => {
    // 获取已有的销售属性
    let hasSaleAttr = supSaleAttrList.value.find((item2) => {
      return item2.baseSaleAttrId == item.id
    })
    return !hasSaleAttr
  })
  return saleAttrList;
})
// 添加销售属性的一个方法
const addSaleAttr = () => {
  // 获取选中的属性值
  let [baseSaleAttrId, saleAttrName] = saleAttrIdAndValueName.value.split(':');

  //  准备一个新的销售属性对象:将来带给服务器即可
  let newSaleAttr: SpuSaleAttrVO = {
    baseSaleAttrId: Number(baseSaleAttrId),
    saleAttrName,
    spuSaleAttrValueList: [
      {
        saleAttrValueName: '',
        baseSaleAttrId: Number(baseSaleAttrId)
      }
    ]
  }
  supSaleAttrList.value.push(newSaleAttr);
  // 清空
  saleAttrIdAndValueName.value = '';
}
//  保存按钮的回调
const save = async () => {
  // 整理参数
  // 1：照片墙的数据
  // spuParam.imageList = imageList.value
  spuParam.value.spuImageList = spuImageList.value.map(item => {
    return {
      imgName: item.name,
      imgUrl: item.url
    }
  })
  // 2.整理销售属性的数据
  spuParam.value.spuSaleAttrList = supSaleAttrList.value.map(item => {
    return {
      baseSaleAttrId: item.baseSaleAttrId,
      saleAttrName: item.saleAttrName,
      spuSaleAttrValueList: item.spuSaleAttrValueList?.map(item => {
        return {
          saleAttrValueName: item.saleAttrValueName
        }
      })
    }
  })
  //  发送请求
  let result = await reqSaveOrUpdateSpu(spuParam.value);
  if (result.code === 200) {
    //  提示信息
    ElMessage.success(spuParam.value.id ? '修改成功' : '添加成功');
    //  关闭对话框
    dialogVisible.value = false;
    //  重新获取数据
    $emit('changeScene', { flag: 0, params: spuParam.value.id ? 'update' : 'add' });
  } else {
    //  提示信息
    ElMessage.error('操作失败');
  }

  // 成功 
  // 失败
}
// 对外暴露
defineExpose({ initHashSpuData, initAddSpu })


function getSpuList(value: any) {
  throw new Error('Function not implemented.');
}
</script>


<style scoped lang="scss"></style>